﻿/*
 * Copyright 2008 Pimm Hogeling, Karim Sempel and Demian Sempel
 * 
 * This file is part of 8bitplays.
 * 
 * 8bitplays is free software: you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the
 * Free Software Foundation, either version 3 of the License, or (at your
 * option) any later version.
 * 
 * 8bitplays is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with 8bitplays. If not, see <http://www.gnu.org/licenses/>.
 */
package nl.sandmen.team.gui {
	import caurina.transitions.Tweener;
	import flash.display.GradientType;
	import flash.display.Graphics;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.geom.Matrix;
	import flash.text.TextField;
	import flash.text.TextFieldAutoSize;
	import flash.text.TextFormat;
	import flash.text.TextFormatAlign;
	import nl.sandmen.team.data.Album;
	import nl.sandmen.team.events.GUIEvent;
	import nl.sandmen.team.filters.Filters;
	import nl.sandmen.team.fonts.Fonts;
	import nl.sandmen.team.tools.GradientTool;
	/**
	 * @author Team Sandmen
	 */
	public class GUI extends Sprite {
		private var afterNextAlbum:AlbumSprite;
		private var albumContainer:Sprite;
		public var bar:Sprite;
		private var beforePreviousAlbum:AlbumSprite;
		private var clearFrames:uint;
		public var controllButtons:ControllButtons;
		private var currentAlbum:AlbumSprite;
		private var dragSprite:Sprite;
		private var nextAlbum:AlbumSprite;
		public var playbackButtons:PlaybackButtons;
		private var previousAlbum:AlbumSprite;
		private var startX:Number;
		private var startY:Number;
		private var statusText:String;
		private var titleField:TextField;
		public function GUI():void {
			albumContainer = new Sprite();
			addEventListener(Event.ADDED, initialize);
		}
		private function clear(e:Event):void {
			if (clearFrames === 0) {
				dragSprite.graphics.clear();
				removeEventListener(Event.ENTER_FRAME, clear);
			} else {
				--clearFrames;
			}
		}
		private function down(e:MouseEvent):void {
			startX = e.stageX;
			startY = e.stageY;
			stage.addEventListener(MouseEvent.MOUSE_MOVE, mouseMove);
			stage.addEventListener(MouseEvent.MOUSE_UP, mouseUp);
			mouseMove(e);
		}
		private function drawBar():void {
			bar = new Sprite();
			addChild(bar);
			var matrix:Matrix = new Matrix();
			matrix.createGradientBox(800, 32, Math.PI * .5);
			bar.buttonMode = true;
			bar.useHandCursor = false;
			bar.doubleClickEnabled = true;
			bar.graphics.beginGradientFill(GradientType.LINEAR, new Array(0x444444, 0x222222), new Array(.8, 1), new Array(0, 0xFF), matrix);
			bar.graphics.drawRect(0, 0, 800, 32);
			bar.graphics.endFill();
		}
		public function initialize(e:Event):void {
			removeEventListener(Event.ADDED, initialize);
			addChild(GradientTool.createGradientBackgroundSprite(0, 32, 800, 470));
			addChild(GradientTool.createGradientFieldSprite(164, 62, 473, 258));
			drawBar();
			if (!titleField) {
				setupField();
			}
			addChild(titleField);
			addChild(albumContainer);
			controllButtons = new ControllButtons();
			controllButtons.x = 730;
			addChild(controllButtons);
			playbackButtons = new PlaybackButtons();
			playbackButtons.x = 400;
			playbackButtons.y = 320;
			addChild(playbackButtons);
			dragSprite = new Sprite();
			addChild(dragSprite);
		}
		public function initializeAlbums(beforePrevious:Album, previous:Album, current:Album, next:Album, afterNext:Album):void {
			beforePreviousAlbum = new AlbumSprite(beforePrevious);
			beforePreviousAlbum.x = 16;
			beforePreviousAlbum.y = 421;
			beforePreviousAlbum.scale = .25;
			beforePreviousAlbum.addEventListener(MouseEvent.MOUSE_DOWN, down);
			albumContainer.addChild(beforePreviousAlbum);
			previousAlbum = new AlbumSprite(previous);
			previousAlbum.x = 45;
			previousAlbum.y = 288;
			previousAlbum.scale = .5;
			previousAlbum.addEventListener(MouseEvent.MOUSE_DOWN, down);
			albumContainer.addChild(previousAlbum);
			currentAlbum = new AlbumSprite(current, AlbumSpriteMaskModes.FULL);
			currentAlbum.x = 400;
			currentAlbum.y = 68;
			currentAlbum.addEventListener(MouseEvent.MOUSE_DOWN, down);
			albumContainer.addChild(currentAlbum);
			nextAlbum = new AlbumSprite(next);
			nextAlbum.x = 641;
			nextAlbum.y = 288;
			nextAlbum.scale = .5;
			nextAlbum.addEventListener(MouseEvent.MOUSE_DOWN, down);
			albumContainer.addChild(nextAlbum);
			afterNextAlbum = new AlbumSprite(afterNext);
			afterNextAlbum.x = 727;
			afterNextAlbum.y = 421;
			afterNextAlbum.scale = .25;
			afterNextAlbum.addEventListener(MouseEvent.MOUSE_DOWN, down);
			albumContainer.addChild(afterNextAlbum);
			updateField();
		}
		public function setStatusText(text:String):void {
			if (titleField) {
				titleField.text = text;
			} else {
				statusText = text;
			}
		}
		private function mouseMove(e:MouseEvent):void {
			const delta:Number = startX - e.stageX;
			const graphics:Graphics = dragSprite.graphics;
			graphics.clear();
			graphics.lineStyle(7, 0x222222, 1, true);
			graphics.moveTo(startX - 6, startY - 5);
			graphics.lineTo(startX + 6, startY + 5);
			graphics.moveTo(startX + 6, startY - 5);
			graphics.lineTo(startX - 6, startY + 5);
			graphics.moveTo(startX, startY);
			graphics.lineTo(e.stageX, e.stageY > 484 ? 484 : e.stageY);
			if (delta < -96) {
				dispatchEvent(new GUIEvent(GUIEvent.GUI_PREVIOUS_ALBUM));
				graphics.lineStyle(4, 0xFFFFFF, 1, true);
				clearFrames = 2;
				mouseUp();
			} else if (delta > 96) {
				dispatchEvent(new GUIEvent(GUIEvent.GUI_NEXT_ALBUM));
				graphics.lineStyle(4, 0xFFFFFF, 1, true);
				clearFrames = 2;
				mouseUp();
			} else {
				graphics.lineStyle(4, 0x3F3F3F + ((delta < 0 ? ~delta + 1 : delta) << 17), 1, true);
			}
			graphics.moveTo(startX - 6, startY - 5);
			graphics.lineTo(startX + 6, startY + 5);
			graphics.moveTo(startX + 6, startY - 5);
			graphics.lineTo(startX - 6, startY + 5);
			graphics.moveTo(startX, startY);
			graphics.lineTo(e.stageX, e.stageY > 484 ? 484 : e.stageY);
		}
		private function mouseUp(e:MouseEvent = null):void {
			addEventListener(Event.ENTER_FRAME, clear);
			stage.removeEventListener(MouseEvent.MOUSE_MOVE, mouseMove);
			stage.removeEventListener(MouseEvent.MOUSE_UP, mouseUp);
		}
		private function setupField():void {
			titleField = new TextField();
			titleField.defaultTextFormat = new TextFormat(Fonts.BN_MACHINE, 24, 0x222222, false, false, false, null, null, TextFormatAlign.CENTER);
			titleField.embedFonts = true;
			titleField.selectable = false;
			titleField.autoSize = TextFieldAutoSize.CENTER;
			titleField.filters = Filters.TEXT_FIELD_SHADOW;
			titleField.width = 0;
			titleField.x = 400;
			titleField.y = 32;
			titleField.text = statusText;
		}
		public function shiftAlbumLeft(afterNext:Album):void {
			currentAlbum.maskMode = AlbumSpriteMaskModes.FRONT;
			nextAlbum.maskMode = AlbumSpriteMaskModes.FULL;
			Tweener.addTween(beforePreviousAlbum, {time:1, x:0, y:500, scale:.25, transition:"easeOutCirc"});
			beforePreviousAlbum.removeEventListener(MouseEvent.MOUSE_DOWN, down);
			beforePreviousAlbum.destroy();
			beforePreviousAlbum = previousAlbum;
			previousAlbum = currentAlbum;
			currentAlbum = nextAlbum;
			nextAlbum = afterNextAlbum;
			afterNextAlbum = new AlbumSprite(afterNext);
			afterNextAlbum.x = 743;
			afterNextAlbum.y = 500;
			afterNextAlbum.scale = .25;
			afterNextAlbum.addEventListener(MouseEvent.MOUSE_DOWN, down);
			albumContainer.addChild(afterNextAlbum);
			updateField();
			tweenAlbums();
		}
		public function shiftAlbumRight(beforePrevious:Album):void {
			currentAlbum.maskMode = AlbumSpriteMaskModes.FRONT;
			previousAlbum.maskMode = AlbumSpriteMaskModes.FULL;
			Tweener.addTween(afterNextAlbum, { time:1, x:743, y:500, scale:.25, transition:"easeOutCirc" } );
			afterNextAlbum.removeEventListener(MouseEvent.MOUSE_DOWN, down);
			afterNextAlbum.destroy();
			afterNextAlbum = nextAlbum;
			nextAlbum = currentAlbum;
			currentAlbum = previousAlbum;
			previousAlbum = beforePreviousAlbum;
			beforePreviousAlbum = new AlbumSprite(beforePrevious);
			beforePreviousAlbum.x = 0;
			beforePreviousAlbum.y = 500;
			beforePreviousAlbum.scale = .25;
			beforePreviousAlbum.addEventListener(MouseEvent.MOUSE_DOWN, down);
			albumContainer.addChild(beforePreviousAlbum);
			updateField();
			tweenAlbums();
		}
		private function tweenAlbums():void {
			Tweener.addTween(beforePreviousAlbum, {time:1, x:16, y:421, scale:.25, transition:"easeOutCirc"});
			Tweener.addTween(previousAlbum, {time:1, x:45, y:288, scale:.5, transition:"easeOutCirc"});
			Tweener.addTween(currentAlbum, {time:1, x:400, y:68, scale:1, transition:"easeOutCirc"});
			Tweener.addTween(nextAlbum, {time:1, x:641, y:288, scale:.5, transition:"easeOutCirc"});
			Tweener.addTween(afterNextAlbum, {time:1, x:727, y:421, scale:.25, transition:"easeOutCirc"});
		}
		private function updateField():void {
			if (!titleField) {
				setupField();
			}
			titleField.text = currentAlbum.title;
		}
	}
}